import pageJson from "@/pages.json";

/**
 * uni跳转路径鉴权，支持动态鉴权及page.json配置的静态鉴权模式，但如果是h5在浏览器中单独访问，则无法拦截，此时可以在App的launch中配置一次window拦截
 * @param  interceptFunc 返回是否鉴权成功，成功则继续执行，否则调用doInFail
 * @param  doInFail 鉴权失败后的处理
 */
function authInUni(interceptFunc, doInFail) {
	let pathList = findPageJsonPaths();
	//使用钩子，进行路由拦截
	const pageRouteMethod = ['navigateTo', 'redirectTo', 'switchTab', 'navigateBack', 'reLaunch'];
	pageRouteMethod.map((item => {
		const originalUni = uni[item];
		uni[item] = function(opt = []) {
			let curUrl = opt.url;
			if (curUrl && curUrl.startsWith("/")) {
				curUrl = curUrl.substring(1);
			}
			//检查鉴权情况
			if (opt.needAuth == undefined) {
				//没有配置鉴权，从page.json中去检查
				for (var i = 0; i < pathList.length; i++) {
					let path = pathList[i].path;
					if (curUrl && curUrl.includes(path)) {
						if (pathList[i].needAuth && !interceptFunc(curUrl, getQueryUrlParams(curUrl))) {
							//需要鉴权,并且鉴权失败
							return doInFail(curUrl);
						} else {
							break;
						}
					}
				}
				//不需要鉴权或者鉴权成功
				return originalUni.call(this, opt);
			} else if (opt.needAuth) {
				//需要鉴权
				if (!interceptFunc(curUrl, getQueryUrlParams(curUrl))) {
					//需要鉴权,并且鉴权失败 
					return doInFail(curUrl);
				} else {
					return originalUni.call(this, opt);
				}
			} else {
				return originalUni.call(this, opt);
			}
		}
	}))
}

/**
 * H5跳转路径鉴权,此方法只可在page.json中配置鉴权，而且会先跳转到特定页面，然后再做鉴权处理
 * @param  interceptFunc 返回是否鉴权成功，成功则继续执行，否则调用doInFail
 * @param  doInFail 鉴权失败后的处理
 */
function authInH5(interceptFunc, doInFail) {
	let pathList = findPageJsonPaths();
	var _wr = function(type) {
		var orig = history[type];
		return function() {
			var e = new Event(type);
			e.arguments = arguments;
			window.dispatchEvent(e);
			// 注意事件监听在url变更方法调用之前 也就是在事件监听的回调函数中获取的页面链接为跳转前的链接
			var rv = orig.apply(this, arguments);
			return rv;
		};
	};
	history.pushState = _wr('pushState');
	history.replaceState = _wr('replaceState');
	window.addEventListener('pushState', function(e) {
		var path = e && e.arguments.length > 2 && e.arguments[2];
		var curUrl = /^http/.test(path) ? path : (location.protocol + '//' + location.host + path);

		for (var i = 0; i < pathList.length; i++) {
			let pathInJson = pathList[i].path;
			if (curUrl.includes(pathInJson)) {

				if (pathList[i].needAuth && !interceptFunc(path, curUrl, getQueryUrlParams(curUrl))) {
					//需要鉴权并且鉴权失败
					return doInFail(curUrl);
				} else {
					break;
				}
			}
		}
	});
	window.addEventListener('replaceState', function(e) {
		var path = e && e.arguments.length > 2 && e.arguments[2];
		var curUrl = /^http/.test(path) ? path : (location.protocol + '//' + location.host + path);

		for (var i = 0; i < pathList.length; i++) {
			let pathInJson = pathList[i].path;
			if (curUrl.includes(pathInJson)) {
				if (pathList[i].needAuth && !interceptFunc(path, curUrl, getQueryUrlParams(curUrl))) {
					//需要鉴权并且鉴权失败
					return doInFail(curUrl);
				} else {
					break;
				}
			}
		}
	});
}

/**
 * 将page.json中的路径数据找到
 */
function findPageJsonPaths() {
	let pathList = [];
	for (var i = 0; i < pageJson.pages.length; i++) {
		let item = pageJson.pages[i];
		pathList.push({
			path: item.path,
			needAuth: item.needAuth
		});
	}
	if (pageJson.subPackages) {
		for (var z = 0; z < pageJson.subPackages.length; z++) {
			let subItem = pageJson.subPackages[z];
			let root = subItem.root;
			for (var j = 0; j < subItem.pages.length; j++) {
				let pageItem = subItem.pages[j];
				if (root && !root.endsWith("/")) {
					root += "/";
				}
				pathList.push({
					path: root + pageItem.path,
					needAuth: pageItem.needAuth
				});
			}
		}
	}
	return pathList;
}

/**
 * 获取url中的参数
 */
function getQueryUrlParams(url) {
	var params = {};
	if (url.indexOf("?") != -1) {
		var str = url.substr(url.indexOf("?") + 1);
		var strs = str.split("&");
		for (var i = 0; i < strs.length; i++) {
			params[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
		}
	}
	return params;
}

export {
	authInUni,
	authInH5
}